from enum import Enum
from typing import NamedTuple
import numpy as np


class Color(Enum):  # 色泽
    white = 1  # 浅白
    green = 2  # 青绿
    black = 3  # 乌黑


class Root(Enum):  # 根蒂
    straight = 1  # 硬挺
    medium = 2  # 稍卷
    curly = 3  # 蜷缩


class Knock(Enum):  # 敲声
    clear = 1  # 清脆
    medium = 2  # 低沉
    deep = 3  # 浊响


class Texture(Enum):
    clear = 1  # 清晰
    medium = 2  # 稍糊
    fuzzy = 3  # 模糊


class Umbilicus(Enum):
    flat = 1  # 平坦
    medium = 2  # 稍凹
    sunken = 3  # 凹陷


class Touch(Enum):
    hard = 1  # 硬滑
    sticky = 2  # 软


class Label(Enum):
    good = 1  # 好瓜
    bad = 2  # 差瓜


class Datum(NamedTuple):
    color: Color
    root: Root
    knock: Knock
    texture: Texture
    umbilicus: Umbilicus
    touch: Touch
    label: Label

    def __repr__(self):
        result_dict = {}
        self_dict = self._asdict()
        for clz in [Color, Root, Knock, Texture, Umbilicus, Touch, Label]:
            name = clz.__name__.lower()
            for item in clz:
                if self_dict[name] == str(item.value):
                    result_dict[name] = item.name
                    break
        return str(result_dict)


class _Data:
    instance = None

    def __init__(self):
        self.data = []
        positives = []
        negatives = []
        X = []
        Y = []
        for line in open('../../../homework_bak/machine_learning/data'):
            items = [float(_) for _ in line.strip().split()]
            self.data.append(Datum(*items))
            x, y = items[:-1], items[-1]
            X.append(x)
            Y.append([y])
            if y == 1:
                positives.append(x)
            else:
                negatives.append(x)
        self.X = np.asarray(X)
        self.Y = np.asarray(Y)
        self.Ps = np.asarray(positives)
        self.Ns = np.asarray(negatives)


def load_data():
    if _Data.instance is None:
        _Data.instance = _Data()

    return _Data.instance
